package com.jeeww.core.dao;

import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.transform.ResultTransformer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.jeeww.core.ext.CustomerAliasToBeanResultTransformer;
import com.jeeww.core.ext.MapResultTransformer;
import com.jeeww.core.utils.AgileUtils;

/**
 * 类描述:用于查询及使用语句进行数据库操作的DAO.
 * @author 蒋文武
 */
@Repository
public class QueryDAO implements QueryDAOInterface {
    /**
     * sessionFactory.
     */
    @Autowired
    private SessionFactory sessionFactory;

    /**
     * @return Session.
     */
    private Session getSession() {
        return sessionFactory.getCurrentSession();
    }

    @Override
    public boolean checkIsHave(final String namedQuery, final Object searchModel) throws Exception {
        String queryString = AgileUtils.stringEvaluate(getSession().getNamedQuery(namedQuery).getQueryString(),
                searchModel);
        SQLQuery query = getSession().createSQLQuery(queryString);
        if (searchModel != null && !"".equals(searchModel)) {
            query.setProperties(searchModel);
        }
        int c = Integer.parseInt(query.list().get(0).toString());
        if (c > 0) {
            return true;
        }
        return false;
    }

    @Override
    public int getCountBySQLNamedQuery(final String namedQuery, final Object searchModel) throws Exception {
        String queryString = AgileUtils.stringEvaluate(getSession().getNamedQuery(namedQuery).getQueryString(),
                searchModel);
        SQLQuery query = getSession().createSQLQuery(queryString);
        if (searchModel != null && !"".equals(searchModel)) {
            query.setProperties(searchModel);
        }
        return Integer.parseInt(query.list().get(0).toString());
    }

    @Override
    public int getCountByHQLNamedQuery(final String namedQuery, final Object searchModel) throws Exception {
        String queryString = AgileUtils.stringEvaluate(getSession().getNamedQuery(namedQuery).getQueryString(),
                searchModel);
        Query query = getSession().createQuery(queryString);
        if (searchModel != null && !"".equals(searchModel)) {
            query.setProperties(searchModel);
        }
        return Integer.parseInt(query.list().get(0).toString());
    }

    @Override
    public int getCountBySQL(final String sql, final Object searchModel) throws Exception {
        String queryString = AgileUtils.stringEvaluate(sql, searchModel);
        SQLQuery query = getSession().createSQLQuery(queryString);
        if (searchModel != null && !"".equals(searchModel)) {
            query.setProperties(searchModel);
        }
        return Integer.parseInt(query.list().get(0).toString());
    }

    @Override
    public int getCountByHQL(final String sql, final Object searchModel) throws Exception {
        String queryString = AgileUtils.stringEvaluate(sql, searchModel);
        Query query = getSession().createQuery(queryString);
        if (searchModel != null && !"".equals(searchModel)) {
            query.setProperties(searchModel);
        }
        return Integer.parseInt(query.list().get(0).toString());
    }

    @SuppressWarnings("unchecked")
    @Override
    public <T> List<T> queryBySQLNamedQuery(final String namedQuery, final Object searchModel) throws Exception {
        String queryString = AgileUtils.stringEvaluate(getSession().getNamedQuery(namedQuery).getQueryString(),
                searchModel);
        SQLQuery query = getSession().createSQLQuery(queryString);
        if (searchModel != null && !"".equals(searchModel)) {
            query.setProperties(searchModel);
        }
        query.setResultTransformer(MapResultTransformer.INSTANCE);
//        query.setCacheable(true);
        return query.list();
    }

    @SuppressWarnings("unchecked")
    @Override
    public <T> List<T> queryByHQLNamedQuery(final String namedQuery, final Object searchModel) throws Exception {
        String queryString = AgileUtils.stringEvaluate(getSession().getNamedQuery(namedQuery).getQueryString(),
                searchModel);
        Query query = getSession().createQuery(queryString);
        if (searchModel != null && !"".equals(searchModel)) {
            query.setProperties(searchModel);
        }
        //query.setCacheable(true);
        return query.list();
    }

    @SuppressWarnings("unchecked")
    @Override
    public <T> List<T> queryBySQLNamedQuery(final String namedQuery, final Object searchModel,
            final Class<?> customerDTO) throws Exception {
        String queryString = AgileUtils.stringEvaluate(getSession().getNamedQuery(namedQuery).getQueryString(),
                searchModel);
        SQLQuery query = getSession().createSQLQuery(queryString);
        if (searchModel != null && !"".equals(searchModel)) {
            query.setProperties(searchModel);
        }
        ResultTransformer transformer = new CustomerAliasToBeanResultTransformer(customerDTO);
        query.setResultTransformer(transformer);
        return query.list();
    }

    @SuppressWarnings("unchecked")
    @Override
    public <T> List<T> queryByHQL(final String hql, final Object searchModel) throws Exception {
        String queryString = AgileUtils.stringEvaluate(hql, searchModel);
        Query query = getSession().createQuery(queryString);
        if (searchModel != null && !"".equals(searchModel)) {
            query.setProperties(searchModel);
        }
        return query.list();
    }

    @SuppressWarnings("unchecked")
    @Override
    public <T> List<T> queryBySQL(final String sql, final Object searchModel) throws Exception {
        String queryString = AgileUtils.stringEvaluate(sql, searchModel);
        SQLQuery query = getSession().createSQLQuery(queryString);
        if (searchModel != null && !"".equals(searchModel)) {
            query.setProperties(searchModel);
        }
        query.setResultTransformer(MapResultTransformer.INSTANCE);
        return query.list();
    }

    @SuppressWarnings("unchecked")
    @Override
    public <T> List<T> queryBySQL(final String sql, final Object searchModel, final Class<?> customerDTO)
            throws Exception {
        String queryString = AgileUtils.stringEvaluate(sql, searchModel);
        SQLQuery query = getSession().createSQLQuery(queryString);
        if (searchModel != null && !"".equals(searchModel)) {
            query.setProperties(searchModel);
        }
        ResultTransformer transformer = new CustomerAliasToBeanResultTransformer(customerDTO);
        query.setResultTransformer(transformer);
        return query.list();
    }

    @Override
    public Criteria createCriteria(final Class<?> c) {
        return getSession().createCriteria(c);
    }

    @Override
    public SQLQuery getSQLQuery(final String sql, final Object searchModel) throws Exception {
        String queryString = AgileUtils.stringEvaluate(sql, searchModel);
        SQLQuery query = getSession().createSQLQuery(queryString);
        if (searchModel != null && !"".equals(searchModel)) {
            query.setProperties(searchModel);
        }
        return query;
    }

    @Override
    public SQLQuery getSQLQueryByNamed(final String namedQuery, final Object searchModel) throws Exception {
        String queryString = AgileUtils.stringEvaluate(getSession().getNamedQuery(namedQuery).getQueryString(),
                searchModel);
        SQLQuery query = getSession().createSQLQuery(queryString);
        if (searchModel != null && !"".equals(searchModel)) {
            query.setProperties(searchModel);
        }
        return query;
    }

    @Override
    public Query getQuery(final String hql, final Object searchModel) throws Exception {
        String queryString = AgileUtils.stringEvaluate(hql, searchModel);
        Query query = getSession().createQuery(queryString);
        if (searchModel != null && !"".equals(searchModel)) {
            query.setProperties(searchModel);
        }
        return query;
    }

    @Override
    public Query getQueryByNamed(final String namedQuery, final Object searchModel) throws Exception {
        String queryString = AgileUtils.stringEvaluate(getSession().getNamedQuery(namedQuery).getQueryString(),
                searchModel);
        Query query = getSession().createQuery(queryString);
        if (searchModel != null && !"".equals(searchModel)) {
            query.setProperties(searchModel);
        }
        return query;
    }

    @Override
    public String getCountQueryStringByNamed(final String namedQuery, final Object searchModel) throws Exception {
        String queryString = AgileUtils.stringEvaluate(getSession().getNamedQuery(namedQuery).getQueryString(),
                searchModel);
        return AgileUtils.getCountQueryString(queryString);
    }

    @Override
    public String getNamedQueryString(final String namedQuery) throws Exception {
        return getSession().getNamedQuery(namedQuery).getQueryString();
    }
}
